/************************************************************
* author: alexander.aivars <alexander.aivars&#64;svt.se>
* $Date:2007-12-19 11:39:12 +0100 (Wed, 19 Dec 2007) $
* $Revision:196 $
* $HeadURL:svn://stoiis03.internt.svt.se/SVTiFLASH/trunk/SVTSE/Source/Classes/se/svt/web/net/HighScore.as $
* $Id:HighScore.as 196 2007-12-19 10:39:12Z alai $
************************************************************/
package se.svt.web.net
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	
	import se.svt.web.events.NetDataRequestEvent;
	import se.svt.web.models.HighScoreData;
	import se.svt.web.models.HighScoreRequestData;
	import se.svt.web.models.NetData;


	/**
	* Dispatched when data has finished loading.
	*
	* @eventType se.svt.web.events.NetDataRequestEvent.COMPLETE
	*/
	[Event(name="NetDataRequstComplete", type="se.svt.web.events.NetDataRequestEvent")]

	/**
	* Dispatched when data has loaded successfully.
	*
	* @eventType se.svt.web.events.NetDataRequestEvent.
	*/
	[Event(name="NetDataRequstSuccess", type="se.svt.web.events.NetDataRequestEvent")]

	/**
	* Dispatched when data has loaded with error response.
	*
	* @eventType se.svt.web.events.NetDataRequestEvent.
	*/
	[Event(name="NetDataRequstFailed", type="se.svt.web.events.NetDataRequestEvent")]

	/**
	* Dispatched when an error occurs that causes a load operation to fail.
	*
	* @eventType se.svt.web.events.NetDataRequestEvent.
	*/
	[Event(name="NetDataRequstError", type="se.svt.web.events.NetDataRequestEvent")]
	
	/**
	 * 
	 * @author Alexander Aivars
	 * 
	 */	
	public class HighScore extends EventDispatcher
	{
		private static const URL_SET:String = "http://svt.se/highscore/sendHighscore.jspa";
		private static const URL_GET:String = "http://svt.se/highscore/queryHighscore.jspa";
		private var _gameId:String;
		private var _model:NetData;
		private var _encryptScore:Boolean;
		
		private function initialize(gameId:String,encrypt:Boolean):void 
		{
			_gameId = gameId;
			_encryptScore = encrypt;
		}
		
		private function reset():void 
		{
			_model = null;
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void {
            dispatchEvent(new NetDataRequestEvent(NetDataRequestEvent.ERROR));
        }
		
		private function addPostListners(dispatcher:IEventDispatcher):void {
            dispatcher.addEventListener(Event.COMPLETE, postComplete);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }
		
		private function removePostListners(dispatcher:IEventDispatcher):void {
            dispatcher.removeEventListener(Event.COMPLETE, postComplete);
            dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

		private function addLoadListners(dispatcher:IEventDispatcher):void {
            dispatcher.addEventListener(Event.COMPLETE, loadComplete);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

		private function removeLoadListners(dispatcher:IEventDispatcher):void {
            dispatcher.removeEventListener(Event.COMPLETE, loadComplete);
            dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

		private function postComplete(event:Event):void {
            var loader:URLLoader = event.target as URLLoader;
			//var response:Namespace  = new Namespace("http://svt.se/xmlnamespaces/svtFlash/externalDataResponse/");

			var xml:XML = new XML(loader.data);

			if(xml..error.toString() == "" && xml..sucess) {
				_model.responseXml = xml;
			} else {
				// ToDo: return error code.
            	dispatchEvent(new NetDataRequestEvent(NetDataRequestEvent.FAILED));
            }

			dispatchEvent(new NetDataRequestEvent(NetDataRequestEvent.COMPLETE));
            reset();
            removePostListners(loader);
        }
        
		private function loadComplete(event:Event):void {
            var loader:URLLoader = event.target as URLLoader;
			// var response:Namespace  = new Namespace("http://svt.se/xmlnamespaces/svtFlash/externalDataResponse/");

			var xml:XML = new XML(loader.data);
			
			if(xml..error.toString() == "" && xml..sucess) {
				_model.responseXml = xml;
				dispatchEvent(new NetDataRequestEvent(NetDataRequestEvent.SUCCESS));
			} else {
				dispatchEvent(new NetDataRequestEvent(NetDataRequestEvent.FAILED));
			}
				dispatchEvent(new NetDataRequestEvent(NetDataRequestEvent.COMPLETE));

            reset();
            removeLoadListners(loader);
        }

		public function HighScore(gameId:String,encrypt:Boolean=false, target:IEventDispatcher=null)
		{
			//TODO: implement function
			super(target);
			initialize(gameId,encrypt);
		}
		
		public function post(model:HighScoreData):void {
			if(_model != null) {
				throw new Error("Data model already waiting for data");
			} else {
				_model = model;
			}
			
			var loader:URLLoader = new URLLoader();
            var request:URLRequest = new URLRequest(URL_SET);
            var variables:URLVariables = new URLVariables();

			variables.gameId = _gameId;
			if( model.email != null ) variables.email = model.email
			if( model.data != null ) variables.data = model.data
			if( model.playerName != null ) variables.playerName = model.playerName
			if( model.score > -1) {
				variables.score = _encryptScore? encryptScore(model.score):model.score;
			}
			
			
			if(model.isMember) {
				variables.isUid = "1"; // this variable dosent seamt to be acepted by the server...??
			}
			if(model.showFocusResult) {
				variables.focusResult = "1";
			}
			
			request.data = variables;
			addPostListners(loader);
			
            try {
            	try {
	                loader.load(request);
            	} catch (error:SecurityError) { 
            		//trace("SecurityError post xmlDb.");
            		reset();
	            	throw error;
            	}
            } catch (error:Error) {
                // trace(error.name +" : Unable to load requested document.");
        		reset();
            	throw error;	
            }			
		}
		
		public function load(model:HighScoreRequestData):void {
			if(_model != null) {
				throw new Error("Data model already waiting for data");
			} else {
				_model = model;
			}
			
			var loader:URLLoader = new URLLoader();
            var request:URLRequest = new URLRequest(URL_GET);
            var variables:URLVariables = new URLVariables();

			variables.gameId = _gameId;
			
			if(model.numOfHighscores != -1) variables.numOfHighscores = model.numOfHighscores;
			if(model.snapshotId != -1) variables.snapshotId = model.snapshotId;
			if(model.startRank != -1) variables.startRank = model.startRank;

			variables.getData = model.showData?1:0;
			variables.showEmptyRanks = model.showEmptyRanks?1:0;
			variables.getPlayerName = model.showPlayerName?1:0;
			variables.getScore = model.showScore?1:0;
			
			
			request.data = variables;
			addLoadListners(loader);
			
            try {
            	try {
	                loader.load(request);
            	} catch (error:SecurityError) { 
            		//trace("SecurityError post xmlDb.");
            		reset();
	            	throw error;
            	}
            } catch (error:Error) {
                // trace(error.name +" : Unable to load requested document.");
        		reset();
            	throw error;	
            }      			
		}
		
		
		public function encryptScore(value:Number):String {
			var str:String = value.toString();
			var result:String = "";
			for (var i:Number=0; i < str.length; i++) {
				var code:String	= str.charCodeAt(i).toString();
				var random:String	= Math.floor(Math.random() * 100).toString();
				
				result = result + code;
				
				if (random.length < 2) {
					random = "0" + random;
				}
				
				result = result + random;
			}
			
			return result;
		}
	}
}